﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameBase;
using System.Threading;

namespace GalaxyPresident
{
    class AI
    {
        Team team;
        static public List<SolarSystem> solarSystems;

        
        int currentPlanet = 0;
        bool isLive = true;

        public bool IsLive
        {
            get { return isLive; }
            set { isLive = value; }
        }
        public AI(Team team)
        {
            this.team = team;
            ThreadStart threadStarter = delegate
            {
                // Do Work Here
                while (isLive)
                {
                    
                    Update();
                    Thread.Sleep(5000 + Constant.random.Next(1000));
                }
            };
            Thread loadingThread = new Thread(threadStarter);
            loadingThread.Start();
        }
        private void Update()
        {
            if (team.Planets.Count == 0)
                return;
            foreach (MotherShip motherShip in team.MotherShips)
            {
                bool own = false;
                foreach(Planet p in team.Planets)
                {
                    if(motherShip.PlanetOwner == p)
                    {
                        own = true;
                    }
                }
                if (!own && motherShip.PlanetOwner!= null)
                {
                    if (Constant.random.NextDouble() > 0.2)
                    {
                        foreach(Block block in motherShip.PlanetOwner.Blocks)
                        {
                            if(block.Entity != null && block.Entity.GetType() == typeof(Capital))
                            {
                                motherShip.Attack(block.Entity);
                            }
                        }
                        
                    }
                    else
                    {
                        motherShip.Withdraw();
                    }
                }
            }
            if (Constant.random.NextDouble() > 0.9f)
            {
                currentPlanet++;
                if (currentPlanet >= team.Planets.Count)
                {
                    currentPlanet = 0;
                }
            }
            CraftStation source=null;
            CraftStation target=null;
            foreach (CraftStation station in team.Planets[currentPlanet].ViewLayer.CraftStations)
            {
                if (station.GetTeamOwner() == team)
                {
                    source = station;
                }
                else
                {
                    target = station;
                }
            }
            if (source != null && target != null)
            {
                source.Attack((PlanetObjectOwner)target);
                return;
            }
            
            if (Constant.random.NextDouble() > 0.6f)
            {
                AutoBuild(team.Planets[currentPlanet]);
            }
            else if (Constant.random.NextDouble() > 0.1f)
            {
                AutoCreateUnit(team.Planets[currentPlanet]);
            }
            else
            {
                AutoAttack(team.Planets[currentPlanet]);
            }
        }
        private void AutoCreateUnit(Planet planet)
        {
            int i = (int)planet.Energy +(int)planet.Meterial ;
            if (i > 1000)
            {
                foreach (Block block in planet.Blocks)
                {
                    if (block.Entity != null && block.Entity.GetType() == typeof(AirPort))
                    {
                        CreateUnitTask task = new CreateUnitTask((AirPort)block.Entity, Constant.random.Next(3));
                        task.Execute();
                    }
                }
            }
        }
        private void AutoAttack(Planet planet)
        {
            MotherShip ship = team.GetMotherShip(planet);
            if (ship==null)
            {
                int i = (int)planet.Energy +(int)planet.Meterial -(team.MotherShips.Count/team.Planets.Count)*3000;

                if (i > 2000)
                {
                    foreach (Block block in planet.Blocks)
                {
                    if (block.Entity != null && block.Entity.GetType() == typeof(AirPort))
                    {
                        CreateMotherShipTask task = new CreateMotherShipTask((AirPort)block.Entity);
                        task.Execute();
                    }
                }
                    
                }
                return;
            }
            
            if (planet.Units.Count > 3)
            {
                List<Planet> targetP=new List<Planet>();
                foreach (SolarSystem ss in solarSystems)
                {
                    foreach (Planet p in ss.Planets)
                    {
                        if (p.GetType() == typeof(LivalePlanet))
                        {
                            bool isowner = false;
                            foreach (Planet tp in team.Planets)
                            {
                                if (tp == p)
                                {
                                    isowner = true;
                                    break;
                                }
                            }
                            if (!isowner)
                            {
                                targetP.Add(p);
                            }
                            
                        }
                    }
                }
                if (targetP.Count == 0)
                    return;
                Planet pl = targetP[Constant.random.Next(targetP.Count)];
                SendWarTask task = new SendWarTask(planet);
                SendingInfo info = new SendingInfo();
                info.Material = (int)(planet.Meterial * (Constant.random.Next(10) + 10) / 100);
                info.Enegry = (int)(planet.Energy * (Constant.random.Next(10) + 10) / 100);
                info.NumberOfUnits = new List<int> {
                                Constant.random.Next(planet.Units.Count/3),
                                Constant.random.Next(planet.Units.Count/3),
                                Constant.random.Next(planet.Units.Count/3)};
                task.SendingInfo = info;
                task.Target = pl;
                task.MotherShip = ship;
                task.Execute();
                return;
            }
        }
        private void AutoBuild(Planet planet)
        {
            ConstructionTask task;
            List<int>  emptyBlock=new List<int>();
            List<int>  wildBlock=new List<int>();
            int nAirPort = 0;
            int nScienticTower = 0;
            int nDefender = 0;
            int nMine = 0;
            int nOldWell = 0;
            int iCapital=-1;
            int i=0;
            foreach (Block block in planet.Blocks)
            {
                if (block.Entity == null)
                {
                    emptyBlock.Add(i);
                }
                else if (block.Entity.GetType() == typeof(AirPort))
                {
                    nAirPort++;
                }
                else if (block.Entity.GetType() == typeof(ScienceTower))
                {
                    nScienticTower++;
                }
                else if (block.Entity.GetType() == typeof(MissileDeffend))
                {
                    nDefender++;
                }
                else if (block.Entity.GetType() == typeof(MeterialExploit))
                {
                    nMine++;
                }
                else if (block.Entity.GetType() == typeof(OilWell))
                {
                    nOldWell++;
                }
                else if (block.Entity.GetType() == typeof(Capital))
                {
                    iCapital = i;
                }
                else
                {
                    wildBlock.Add(i);
                }
                i++;
            }
            int energy = (int)planet.Energy + nOldWell * 500;
            int material = (int)planet.Meterial + nMine * 500;
            int defend = (nDefender+1) * 5000;
            int attack = nAirPort * 10000;
            int iblock = 0;
            
            if (emptyBlock.Count == 0)
            {
                if (wildBlock.Count > planet.BlockCount / 3)
                {
                    iblock = FindBlock(wildBlock);
                    task = new ClearTask();

                }
                else
                {
                    return;
                }
            }
            else
            {
                iblock = FindBlock(emptyBlock);
                 if (attack < material && attack < energy && material > 2500)
                {
                    task = new BuildingTask(new AirPort(planet));
                }
                else if (defend < material && defend < energy && energy > 2500)
                {
                    task = new BuildingTask(new MissileDeffend(planet));
                }
                
                else if (energy < material)
                {
                    task = new BuildingTask(new OilWell(planet));
                }
                else
                {
                    task = new BuildingTask(new MeterialExploit(planet));
                }
               
            }
            task.Planet = planet;
            task.BlockIndex = iblock;
            task.Execute();
        }
        public int FindBlock(List<int> blocks)
        {
            return blocks[Constant.random.Next(blocks.Count)];

        }
    }
}
